package com.kedacom.demo.ad.service;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;
import javax.naming.directory.DirContext;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.ldap.core.DirContextOperations;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.core.support.AbstractContextMapper;
import org.springframework.ldap.query.LdapQueryBuilder;
import org.springframework.ldap.support.LdapUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.kedacom.demo.ad.model.ADUser;
import com.kedacom.demo.ad.model.ADUser.ADUserAttributesMapper;

@Service("adUserService")
public class ADUserService {

	@Resource
	private LdapTemplate ldapTemplate;
	@Value("${ldap.domains}")
	private String domains;

	private ADUserAttributesMapper userAttributesMapper = new ADUserAttributesMapper();

	public static class DNMapper extends AbstractContextMapper<String> {

		@Override
		protected String doMapFromContext(DirContextOperations ctx) {
			return ctx.getNameInNamespace();
		}
	}

	public ADUser login(String username, String password) {
		DirContext ctx = null;
		try {
			ldapTemplate.getContextSource().getContext(username, password);
			return getByUsername(username);
		} catch (Exception e) {
			return null;
		} finally {
			LdapUtils.closeContext(ctx);
		}
	}

	public ADUser getByUsername(String username) {
		String shortUsername = username;
		if (username.contains("\\")) {
			shortUsername = username.substring(username.indexOf("\\") + 1);
			// System.out.println(shortUsername);
		}
		if (username.contains("@")) {
			shortUsername = username.substring(0, username.indexOf("@"));
			// System.out.println(shortUsername);
		}
		List<ADUser> users = ldapTemplate.search(LdapQueryBuilder.query().where("userPrincipalName").is(shortUsername)
				.or("sAMAccountName").is(shortUsername), userAttributesMapper);
		return CollectionUtils.isEmpty(users) ? null : users.get(0);
	}

	public List<ADUser> listUsers() {
		return ldapTemplate.search(
				LdapQueryBuilder.query().where("objectCategory").is("person").and("objectClass").is("user"),
				userAttributesMapper);
	}

	public List<String> getDomains() {
		String[] domainArray = StringUtils.commaDelimitedListToStringArray(domains);
		List<String> domainList = new ArrayList<String>();
		for (String domain : domainArray) {
			if (!StringUtils.isEmpty(domain)) {
				if (!domain.contains("\\")) {
					domainList.add(domain + "\\");
				} else {
					domainList.add(domain);
				}
			}
		}
		return domainList;
	}

}
